/** Description of MyDBWrapper.java 
 *
 * @author panther
 * Jayant Pratim Saikia
 * jay.saikia@gmail.com
 *
 */
package com.panther.awp.android.smoker.database;

import java.text.ParseException;
import java.util.Date;

import com.panther.awp.android.smoker.logical.NumberComparator;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;

public class MyDBWrapper {
	
	private static MyDBWrapper myDBWrapperInstance = null;
	private TTDbAdapter mTTDbHelper;
	private DTDbAdapter mDTDbHelper;
	private BTDbAdapter mBTDbHelper;
	private MTDbAdapter mMTDbHelper;
	private WTDbAdapter mWTDbHelper;
	
	private MyDBWrapper(Context ctx) {
		mTTDbHelper = new TTDbAdapter(ctx);
		mTTDbHelper.open();
		mDTDbHelper = new DTDbAdapter(ctx);
		mDTDbHelper.open();
		mBTDbHelper = new BTDbAdapter(ctx);
		mBTDbHelper.open();
		mWTDbHelper = new WTDbAdapter(ctx);
		mWTDbHelper.open();
		mMTDbHelper = new MTDbAdapter(ctx);
		mMTDbHelper.open();
	}
	
	public static MyDBWrapper getInstance(Context context) {
		if(myDBWrapperInstance == null) {
			myDBWrapperInstance = new MyDBWrapper(context);
		}
		return myDBWrapperInstance;
	}

	public TTDbAdapter getmTTDbHelper() {
		return mTTDbHelper;
	}
	
	public DTDbAdapter getmDTDbHelper() {
		return mDTDbHelper;
	}

	public BTDbAdapter getmBTDbHelper() {
		return mBTDbHelper;
	}

	public MTDbAdapter getmMTDbHelper() {
		return mMTDbHelper;
	}

	public WTDbAdapter getmWTDbHelper() {
		return mWTDbHelper;
	}
	
	/**
	 * @param smokeDate Smoke Date Time Stamp
	 * @param brand Brand That was smoked
	 * @param price Price of smoke
	 */
	public void insertSmokeNow(Long brandId) {
		Cursor brandCursor = mBTDbHelper.fetch(brandId);
		if(brandCursor.getCount() == 1) {
			brandCursor.moveToFirst();
			Double price = brandCursor.getDouble(brandCursor.getColumnIndexOrThrow(AbstractDbAdapter.BT_BRAND_PRICE));
			int brandCount = brandCursor.getInt(brandCursor.getColumnIndexOrThrow(AbstractDbAdapter.BT_NO_OF_CIGGS));
			
			//First Update smoke count in brands table
			updateBrandsTrackItem(brandId, brandCount);
			
			//Second insert a record in times track table
			insertIntoTimesTrack(price, brandId);
			
			//Third check if times track table has exceeded two weeks and delete these older records
			checkAndDeleteTimesTrackItems();
			
			//Fourth check if days track table has exceeded two weeks and delete these older records
			insertIntoDaysTrack(price);
			
			//Fifth insert or update weeks table by checking if its a new week or not
			insertIntoWeeksTrack(price);
			
			//Sixth insert or update months table by checking if its a new month or not
			insertIntoMonthsTrack(price);
		}
		brandCursor.close();
	}

	private void updateBrandsTrackItem(Long _id, int brandCount) {
		ContentValues values = new ContentValues();
		values.put(AbstractDbAdapter.BT_NO_OF_CIGGS, ++brandCount);
		mBTDbHelper.update(_id, values);
	}

	private void insertIntoTimesTrack(Double price, Long brandId) {
		ContentValues values = new ContentValues();
		Date date = new Date();
		values.put(AbstractDbAdapter.TT_DATETIME, AbstractDbAdapter.DATE_FORMAT.format(date));
		values.put(AbstractDbAdapter.TT_BRAND_ID, brandId);
		values.put(AbstractDbAdapter.TT_COST, price);
		mTTDbHelper.create(values);
	}

	private void insertIntoMonthsTrack(Double price) {
		Date now = new Date();
		Cursor latestCursor = mMTDbHelper.fetchLatest();
		if(latestCursor.getCount() == 0) {
			ContentValues values = new ContentValues();
			values.put(AbstractDbAdapter.MT_COST, price);
			values.put(AbstractDbAdapter.MT_NO_OF_CIGGS, 1);
			values.put(AbstractDbAdapter.MT_STARTDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getMonthStartingDate(now)));
			values.put(AbstractDbAdapter.MT_ENDDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getMonthEndingDate(now)));
			mMTDbHelper.create(values);
		} else {
			latestCursor.moveToFirst();
			try {
				Date monthStartDate = AbstractDbAdapter.DATE_FORMAT.parse(latestCursor.getString(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.MT_STARTDATE)));
				Date monthEndDate = AbstractDbAdapter.DATE_FORMAT.parse(latestCursor.getString(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.MT_ENDDATE)));
				if(monthStartDate.before(now) && monthEndDate.after(now)) {
					Long _id = latestCursor.getLong(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.MT_PK_ID));
					Double oldCost = latestCursor.getDouble(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.MT_COST));
					int count = latestCursor.getInt(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.MT_NO_OF_CIGGS));
					ContentValues values = new ContentValues();
					values.put(AbstractDbAdapter.MT_COST, oldCost + price);
					values.put(AbstractDbAdapter.MT_NO_OF_CIGGS, ++count);
					mMTDbHelper.update(_id, values);
				} else {
					ContentValues values = new ContentValues();
					values.put(AbstractDbAdapter.MT_COST, price);
					values.put(AbstractDbAdapter.MT_NO_OF_CIGGS, 1);
					values.put(AbstractDbAdapter.MT_STARTDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getMonthStartingDate(now)));
					values.put(AbstractDbAdapter.MT_ENDDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getMonthEndingDate(now)));
					mMTDbHelper.create(values);
				}
			} catch (ParseException e) {
				
			}
		}
		
		latestCursor.close();
	}

	private void insertIntoWeeksTrack(Double price) {
		Date now = new Date();
		Cursor latestCursor = mWTDbHelper.fetchLatest();
		if(latestCursor.getCount() == 0) {
			ContentValues values = new ContentValues();
			values.put(AbstractDbAdapter.WT_COST, price);
			values.put(AbstractDbAdapter.WT_NO_OF_CIGGS, 1);
			values.put(AbstractDbAdapter.WT_STARTDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getWeekStartingDate(now)));
			values.put(AbstractDbAdapter.WT_ENDDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getWeekEndingDate(now)));
			mWTDbHelper.create(values);
		} else {
			latestCursor.moveToFirst();
			try {
				Date weekStartDate = AbstractDbAdapter.DATE_FORMAT.parse(latestCursor.getString(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.WT_STARTDATE)));
				Date weekEndDate = AbstractDbAdapter.DATE_FORMAT.parse(latestCursor.getString(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.WT_ENDDATE)));
				if(weekStartDate.before(now) && weekEndDate.after(now)) {
					Long _id = latestCursor.getLong(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.WT_PK_ID));
					Double oldCost = latestCursor.getDouble(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.WT_COST));
					int count = latestCursor.getInt(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.WT_NO_OF_CIGGS));
					ContentValues values = new ContentValues();
					values.put(AbstractDbAdapter.WT_COST, oldCost + price);
					values.put(AbstractDbAdapter.WT_NO_OF_CIGGS, ++count);
					mWTDbHelper.update(_id, values);
				} else {
					ContentValues values = new ContentValues();
					values.put(AbstractDbAdapter.WT_COST, price);
					values.put(AbstractDbAdapter.WT_NO_OF_CIGGS, 1);
					values.put(AbstractDbAdapter.WT_STARTDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getWeekStartingDate(now)));
					values.put(AbstractDbAdapter.WT_ENDDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getWeekEndingDate(now)));
					mWTDbHelper.create(values);
				}
			} catch (ParseException e) {
				
			}
		}
		
		latestCursor.close();
	}
	
	private void insertIntoDaysTrack(Double price) {
		Date now = new Date();
		Cursor latestCursor = mDTDbHelper.fetchLatest();
		if(latestCursor.getCount() == 0) {
			ContentValues values = new ContentValues();
			values.put(AbstractDbAdapter.DT_COST, price);
			values.put(AbstractDbAdapter.DT_NO_OF_CIGGS, 1);
			values.put(AbstractDbAdapter.DT_STARTDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getDayStartingDate(now)));
			values.put(AbstractDbAdapter.DT_ENDDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getDayEndingDate(now)));
			mDTDbHelper.create(values);
		} else {
			latestCursor.moveToFirst();
			try {
				Date dayStartDate = AbstractDbAdapter.DATE_FORMAT.parse(latestCursor.getString(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_STARTDATE)));
				Date dayEndDate = AbstractDbAdapter.DATE_FORMAT.parse(latestCursor.getString(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_ENDDATE)));
				if(dayStartDate.before(now) && dayEndDate.after(now)) {
					Long _id = latestCursor.getLong(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_PK_ID));
					Double oldCost = latestCursor.getDouble(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_COST));
					int count = latestCursor.getInt(latestCursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_NO_OF_CIGGS));
					ContentValues values = new ContentValues();
					values.put(AbstractDbAdapter.DT_COST, oldCost + price);
					values.put(AbstractDbAdapter.DT_NO_OF_CIGGS, ++count);
					mDTDbHelper.update(_id, values);
				} else {
					ContentValues values = new ContentValues();
					values.put(AbstractDbAdapter.DT_COST, price);
					values.put(AbstractDbAdapter.DT_NO_OF_CIGGS, 1);
					values.put(AbstractDbAdapter.DT_STARTDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getDayStartingDate(now)));
					values.put(AbstractDbAdapter.DT_ENDDATE, AbstractDbAdapter.DATE_FORMAT.format(NumberComparator.getInstance().getDayEndingDate(now)));
					mDTDbHelper.create(values);
				}
			} catch (ParseException e) {
				
			}
		}
		
		latestCursor.close();
	}

	private void checkAndDeleteTimesTrackItems() {
		Cursor latestSmokeCursor = mTTDbHelper.fetchLatestSmokeEntry();
		latestSmokeCursor.moveToFirst();
		while(!latestSmokeCursor.isAfterLast()) {
			try {
				Date latestSmokeDate = AbstractDbAdapter.DATE_FORMAT.parse(latestSmokeCursor.getString(latestSmokeCursor.getColumnIndexOrThrow(AbstractDbAdapter.TT_DATETIME)));
				Date fortNightDate = NumberComparator.getInstance().getWeekFortnightStartingDate(latestSmokeDate);
				Cursor oldDataCursor = mTTDbHelper.fetchEntryOlderThan(fortNightDate);
				oldDataCursor.moveToFirst();
				while(!oldDataCursor.isAfterLast()) {
					Long _id = oldDataCursor.getLong(oldDataCursor.getColumnIndexOrThrow(AbstractDbAdapter.TT_PK_ID));
					mTTDbHelper.delete(_id);
					oldDataCursor.moveToNext();
				}
				oldDataCursor.close();
			} catch (ParseException e) {
				
			}
			latestSmokeCursor.moveToNext();
		}
		latestSmokeCursor.close();
	}

}
